package com.wangdao.wechatmall.service.admin;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wangdao.wechatmall.bean.bo.admin.GoodsCreateBO;
import com.wangdao.wechatmall.bean.bo.admin.GoodsParamBO;
import com.wangdao.wechatmall.bean.pojo.*;
import com.wangdao.wechatmall.bean.vo.admin.*;
import com.wangdao.wechatmall.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author ZhangXiao on 2021/7/8
 */
@Service
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    GoodsMapper goodsMapper;

    @Autowired
    GoodsAttributeMapper goodsAttributeMapper;

    @Autowired
    GoodsSpecificationMapper goodsSpecificationMapper;

    @Autowired
    GoodsProductMapper goodsProductMapper;

    @Autowired
    CategoryMapper categoryMapper;

    @Autowired
    BrandMapper brandMapper;

    @Override
    public long getGoodsNumber() {
        GoodsExample goodsExample = new GoodsExample();
        long goodsTotal = goodsMapper.countByExample(goodsExample);
        return goodsTotal;

    }

    /**
     * 查询商品列表
     * @param param
     * @return
     */
    @Override
    public BaseDataVO<Goods> queryGoodsList(GoodsParamBO param) {
        // 通过PageHelper进行分页查询
        PageHelper.startPage(param.getPage(), param.getLimit());

        GoodsExample goodsExample = new GoodsExample();

        GoodsExample.Criteria criteria = goodsExample.createCriteria();

        if (!StringUtils.isEmpty(param.getGoodsSn())) {
            criteria.andGoodsSnEqualTo(param.getGoodsSn());
        }

        if (!StringUtils.isEmpty(param.getName())) {
            criteria.andNameLike("%" + param.getName() + "%");
        }
        criteria.andDeletedEqualTo(false);

        // 设置分页查询
        goodsExample.setOrderByClause(param.getSort() + " " + param.getOrder());

        List<Goods> goods = goodsMapper.selectByExampleWithBLOBs(goodsExample);
        // 在执行完查询操作之后可以获得分页信息，查询结果会放在PageInfo的构造方法当中
        PageInfo<Goods> goodsPageInfo = new PageInfo<>(goods);
        long total = goodsPageInfo.getTotal();
        //long total = goodsMapper.countByExample(goodsExample);

        return BaseDataVO.ok(goods, total);
    }

    /**
     * 根据id删除商品，这里的删除商品是逻辑删除，只需要修改goods的deleted为1
     * @param goods
     * @return
     */
    @Override
    public int deleteGoods(Goods goods) {
        Goods goodsToDelete = new Goods();
        goodsToDelete.setId(goods.getId());
        goodsToDelete.setDeleted(true);
        goodsToDelete.setUpdateTime(new Date());

        int affectedRows = goodsMapper.updateByPrimaryKeySelective(goodsToDelete);

        return affectedRows;
    }

    /**
     * 查询父商品种类及对应的子商品种类以及所有品牌商
     * @return
     */
    @Override
    public CatAndBrandVO showCatAndBrand() {
        CatAndBrandVO catAndBrandVO = new CatAndBrandVO();

        // 查询父商品种类列表
        CategoryExample categoryExample = new CategoryExample();
        CategoryExample.Criteria categoryExampleCriteria = categoryExample.createCriteria();
        categoryExampleCriteria.andPidEqualTo(0);
        List<Category> categories = categoryMapper.selectByExample(categoryExample);

        List<CategoryOfCatAndBrandVO> categoryOfCatAndBrandVOS = new ArrayList<>();
        for (Category category : categories) {
            CategoryOfCatAndBrandVO categoryOfCatAndBrandVO = new CategoryOfCatAndBrandVO();

            // 查询子商品种类
            CategoryExample categoryExample2 = new CategoryExample();
            CategoryExample.Criteria categoryExample2Criteria = categoryExample2.createCriteria();
            categoryExample2Criteria.andPidEqualTo(category.getId());
            List<Category> childrenCategoryList = categoryMapper.selectByExample(categoryExample2);
            List<ChildrenOfCatAndBrandVO> childrenOfCatAndBrandVOS = new ArrayList<>();
            for (Category childrenCategory : childrenCategoryList) {
                ChildrenOfCatAndBrandVO childrenOfCatAndBrandVO = new ChildrenOfCatAndBrandVO();
                childrenOfCatAndBrandVO.setValue(childrenCategory.getId());
                childrenOfCatAndBrandVO.setLabel(childrenCategory.getName());
                childrenOfCatAndBrandVOS.add(childrenOfCatAndBrandVO);
            }
            categoryOfCatAndBrandVO.setValue(category.getId());
            categoryOfCatAndBrandVO.setLabel(category.getName());
            categoryOfCatAndBrandVO.setChildren(childrenOfCatAndBrandVOS);
            categoryOfCatAndBrandVOS.add(categoryOfCatAndBrandVO);
        }
        catAndBrandVO.setCategoryList(categoryOfCatAndBrandVOS);

        // 查询品牌商列表
        BrandExample brandExample = new BrandExample();
        List<Brand> brands = brandMapper.selectByExample(brandExample);
        List<BrandOfCatAndBrandVO> brandOfCatAndBrandVOS = new ArrayList<>();
        for (Brand brand : brands) {
            BrandOfCatAndBrandVO brandOfCatAndBrandVO = new BrandOfCatAndBrandVO();
            brandOfCatAndBrandVO.setValue(brand.getId());
            brandOfCatAndBrandVO.setLabel(brand.getName());
            brandOfCatAndBrandVOS.add(brandOfCatAndBrandVO);
        }
        catAndBrandVO.setBrandList(brandOfCatAndBrandVOS);

        return catAndBrandVO;
    }

    /**
     * 查询商品详情
     * @param id
     * @return
     */
    @Override
    public GoodsDetailVO queryGoodsDetail(Integer id) {
        GoodsDetailVO goodsDetailVO = new GoodsDetailVO();

        // 根据id查询商品信息
        Goods goods = goodsMapper.selectByPrimaryKey(id);
        goodsDetailVO.setGoods(goods);

        // 根据子商品种类id查询父商品种类id
        Category category = categoryMapper.selectByPrimaryKey(goods.getCategoryId());

        List<Integer> categoryIds = new ArrayList<>();
        categoryIds.add(category.getPid());
        categoryIds.add(category.getId());
        goodsDetailVO.setCategoryIds(categoryIds);

        // 根据商品id查询attributes
        GoodsAttributeExample goodsAttributeExample = new GoodsAttributeExample();
        GoodsAttributeExample.Criteria goodsAttributeExampleCriteria = goodsAttributeExample.createCriteria();
        goodsAttributeExampleCriteria.andGoodsIdEqualTo(goods.getId());
        goodsAttributeExampleCriteria.andDeletedEqualTo(false);

        List<GoodsAttribute> attributes = goodsAttributeMapper.selectByExample(goodsAttributeExample);
        goodsDetailVO.setAttributes(attributes);

        // 根据商品id查询specifications
        GoodsSpecificationExample goodsSpecificationExample = new GoodsSpecificationExample();
        GoodsSpecificationExample.Criteria goodsSpecificationExampleCriteria = goodsSpecificationExample.createCriteria();
        goodsSpecificationExampleCriteria.andGoodsIdEqualTo(goods.getId());
        goodsSpecificationExampleCriteria.andDeletedEqualTo(false);

        List<GoodsSpecification> specifications = goodsSpecificationMapper.selectByExample(goodsSpecificationExample);
        goodsDetailVO.setSpecifications(specifications);

        // 根据商品id查询products
        GoodsProductExample goodsProductExample = new GoodsProductExample();
        GoodsProductExample.Criteria goodsProductExampleCriteria = goodsProductExample.createCriteria();
        goodsProductExampleCriteria.andGoodsIdEqualTo(goods.getId());
        goodsProductExampleCriteria.andDeletedEqualTo(false);

        List<GoodsProduct> products = goodsProductMapper.selectByExample(goodsProductExample);
        goodsDetailVO.setProducts(products);

        return goodsDetailVO;
    }

    /**
     * 添加商品及商品对应的specifications、products、attributes
     * 如果插入成功返回1，商品编号重复返回401
     * @param goodsCreateBO
     * @return
     */
    @Transactional
    @Override
    public int addGoods(GoodsCreateBO goodsCreateBO) {
        // 获取当前日期
        Date currentDate = new Date();
        Goods goods = goodsCreateBO.getGoods();
        int goodsSn = Integer.parseInt(goods.getGoodsSn());

        // 还需要设置商品的id(和goodsSn相等)，createTime,updateTime
        goods.setId(goodsSn);
        goods.setAddTime(currentDate);
        goods.setUpdateTime(currentDate);
        
        // 插入前先判断新增的商品id和数据库中的id是否有重复
        Goods goodsIdRepeatable = goodsMapper.selectByPrimaryKey(goodsSn);
        if (goodsIdRepeatable != null) {
            return 401;
        }

        // 插入goods
        int affectedRows = goodsMapper.insertSelective(goods);

        // 获取商品id
        Integer goodsId = goods.getId();

        // 还需要设置specification的goodsId，createTime，updateTime
        List<GoodsSpecification> specifications = goodsCreateBO.getSpecifications();
        for (GoodsSpecification specification : specifications) {
            specification.setGoodsId(goodsId);
            specification.setAddTime(currentDate);
            specification.setUpdateTime(currentDate);

            // 插入specifications
            goodsSpecificationMapper.insertSelective(specification);
        }

        // 还需要设置product的的goodsId，createTime，updateTime
        // 这里product接收到的id并非product在数据库中的id，而是代表第几个product，此处attribute的id设置为null，插入数据库时会自动添加id
        List<GoodsProduct> products = goodsCreateBO.getProducts();
        for (GoodsProduct product : products) {
            product.setGoodsId(goodsId);
            product.setAddTime(currentDate);
            product.setUpdateTime(currentDate);

            // 这里product接收到的id并非product在数据库中的id，而是代表第几个product，此处attribute的id设置为null，插入数据库时会自动添加id
            product.setId(null);

            // 插入products
            goodsProductMapper.insertSelective(product);
        }

        // 还需要设置attribute的goodsId，createTime，updateTime。
        List<GoodsAttribute> attributes = goodsCreateBO.getAttributes();
        for (GoodsAttribute attribute : attributes) {
            attribute.setGoodsId(goodsId);
            attribute.setAddTime(currentDate);
            attribute.setUpdateTime(currentDate);

            // 插入attributes
            goodsAttributeMapper.insertSelective(attribute);
        }

        return affectedRows;
    }

    /**
     * 更新商品及商品对应的specifications、products、attributes
     * @param goodsCreateBO
     * @return
     */
    @Transactional
    @Override
    public int updateGoods(GoodsCreateBO goodsCreateBO) {
        // 获取更新后的goods、specifications、products、attributes
        Goods goods = goodsCreateBO.getGoods();
        List<GoodsSpecification> specifications = goodsCreateBO.getSpecifications();
        List<GoodsProduct> products = goodsCreateBO.getProducts();
        List<GoodsAttribute> attributes = goodsCreateBO.getAttributes();

        // 获取商品id
        Integer goodsId = goods.getId();

        // 获取当前日期
        Date currentDate = new Date();

        // 查询商品已有的specifications
        GoodsSpecificationExample goodsSpecificationExample1 = new GoodsSpecificationExample();
        GoodsSpecificationExample.Criteria goodsSpecificationExample1Criteria = goodsSpecificationExample1.createCriteria();
        goodsSpecificationExample1Criteria.andGoodsIdEqualTo(goodsId);
        List<GoodsSpecification> goodsSpecifications = goodsSpecificationMapper.selectByExample(goodsSpecificationExample1);
        ArrayList<Integer> goodsSpecificationIds = new ArrayList<>();
        for (GoodsSpecification goodsSpecification : goodsSpecifications) {
            goodsSpecificationIds.add(goodsSpecification.getId());
        }

        // 查询商品已有的products
        GoodsProductExample goodsProductExample1 = new GoodsProductExample();
        GoodsProductExample.Criteria goodsProductExample1Criteria = goodsProductExample1.createCriteria();
        goodsProductExample1Criteria.andGoodsIdEqualTo(goodsId);
        List<GoodsProduct> goodsProducts = goodsProductMapper.selectByExample(goodsProductExample1);
        ArrayList<Integer> goodsProductIds = new ArrayList<>();
        for (GoodsProduct goodsProduct : goodsProducts) {
            goodsProductIds.add(goodsProduct.getId());
        }

        // 查询商品已有的attributes
        GoodsAttributeExample goodsAttributeExample1 = new GoodsAttributeExample();
        GoodsAttributeExample.Criteria goodsAttributeExample1Criteria = goodsAttributeExample1.createCriteria();
        goodsAttributeExample1Criteria.andGoodsIdEqualTo(goodsId);
        List<GoodsAttribute> goodsAttributes = goodsAttributeMapper.selectByExample(goodsAttributeExample1);
        ArrayList<Integer> goodsAttributeIds = new ArrayList<>();
        for (GoodsAttribute goodsAttribute : goodsAttributes) {
            goodsAttributeIds.add(goodsAttribute.getId());
        }

        // 更新商品
        goods.setUpdateTime(currentDate);
        int affectedRows = goodsMapper.updateByPrimaryKeySelective(goods);

        GoodsSpecificationExample goodsSpecificationExample = new GoodsSpecificationExample();
        GoodsSpecificationExample.Criteria goodsSpecificationExampleCriteria = goodsSpecificationExample.createCriteria();
        goodsSpecificationExampleCriteria.andGoodsIdEqualTo(goodsId);
        GoodsSpecification goodsSpecificationDelete = new GoodsSpecification();
        goodsSpecificationDelete.setUpdateTime(currentDate);
        goodsSpecificationDelete.setDeleted(true);
        // 更新specifications，先根据goodsId删除原有的specifications(设置deleted=1)，再插入新的specifications
        goodsSpecificationMapper.updateByExampleSelective(goodsSpecificationDelete, goodsSpecificationExample);
        for (GoodsSpecification specification : specifications) {
            specification.setUpdateTime(currentDate);
            goodsSpecificationMapper.updateByPrimaryKeySelective(specification);
            if (!goodsSpecificationIds.contains(specification.getId())) {
                // 新增的specification没有携带goodsId，addTime，updateTime
                specification.setGoodsId(goodsId);
                specification.setAddTime(currentDate);
                goodsSpecificationMapper.insertSelective(specification);
            }
        }

        GoodsProductExample goodsProductExample = new GoodsProductExample();
        GoodsProductExample.Criteria goodsProductExampleCriteria = goodsProductExample.createCriteria();
        goodsProductExampleCriteria.andGoodsIdEqualTo(goodsId);
        GoodsProduct goodsProductDelete = new GoodsProduct();
        goodsProductDelete.setUpdateTime(currentDate);
        goodsProductDelete.setDeleted(true);
        // 更新products，先根据goodsId删除原有的products(设置deleted为1)，再插入新的products
        goodsProductMapper.updateByExampleSelective(goodsProductDelete, goodsProductExample);
        for (GoodsProduct product : products) {
            product.setUpdateTime(currentDate);
            goodsProductMapper.updateByPrimaryKeySelective(product);
            if (!goodsProductIds.contains(product.getId())) {
                // 新增product的时候会给product自动设置从0开始的id，可能会导致id重复，故这里将新增的product的id设置为null
                product.setId(null);
                // 新增的product没有携带goodsId，addTime，updateTime
                product.setGoodsId(goodsId);
                product.setAddTime(currentDate);
                goodsProductMapper.insertSelective(product);
            }
        }

        GoodsAttributeExample goodsAttributeExample = new GoodsAttributeExample();
        GoodsAttributeExample.Criteria goodsAttributeExampleCriteria = goodsAttributeExample.createCriteria();
        goodsAttributeExampleCriteria.andGoodsIdEqualTo(goodsId);
        GoodsAttribute goodsAttributeDelete = new GoodsAttribute();
        goodsAttributeDelete.setUpdateTime(currentDate);
        goodsAttributeDelete.setDeleted(true);
        // 更新attributes，先根据goodsId删除原有的attributes(设置deleted为1)，再插入新的attributes
        goodsAttributeMapper.updateByExampleSelective(goodsAttributeDelete, goodsAttributeExample);
        for (GoodsAttribute attribute : attributes) {
            attribute.setUpdateTime(currentDate);
            goodsAttributeMapper.updateByPrimaryKeySelective(attribute);
            if (!goodsAttributeIds.contains(attribute.getId())) {
                // 新增的attribute没有携带goodsId，addTime，updateTime
                attribute.setGoodsId(goodsId);
                attribute.setAddTime(currentDate);
                goodsAttributeMapper.insertSelective(attribute);
            }
        }

        return affectedRows;
    }
}
